package com.mrx.commons.utils;

import lombok.SneakyThrows;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Mr.X
 * @since 2023-12-08 14:04
 **/
public class ThreadUtils {

    private static final AtomicInteger THREAD_COUNT = new AtomicInteger();

    @SneakyThrows
    public static void safeSleep(long sleepTime, TimeUnit timeUnit) {
        timeUnit.sleep(sleepTime);
    }

    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory, String namePrefix) {
        TimeUnit unit = TimeUnit.MILLISECONDS;
        LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        ThreadFactory decoratedThreadFactory = it -> decorateThread(threadFactory.newThread(it), namePrefix);
        return new XThreadPoolExecutor(nThreads, nThreads, 0L, unit, workQueue, decoratedThreadFactory);
    }

    private static Thread decorateThread(Thread thread, String namePrefix) {
        thread.setName(namePrefix + "-" + THREAD_COUNT.getAndIncrement());
        return thread;
    }

    private static final class XThreadPoolExecutor extends ThreadPoolExecutor {

        public XThreadPoolExecutor(
                int corePoolSize,
                int maximumPoolSize,
                long keepAliveTime,
                TimeUnit unit,
                BlockingQueue<Runnable> workQueue,
                ThreadFactory threadFactory
        ) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                    threadFactory);
        }

        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
        }

    }

}
